



import os 
import sys
import time
import numpy as np
import matplotlib.pyplot as plt
from PIL import Image
import cv2

from os.path import join,split,exists
from tqdm import tqdm 
import shutil
import json 
from concurrent import futures



def load_json(file_name):

    assert exists(file_name)
    with open(file_name)as f:
        body_qualities = json.load(f)

    return body_qualities



def make_dir(tgt_dir):
    if not exists(tgt_dir):
        os.makedirs(tgt_dir)
    

def show_img(img_path):

    plt.imshow(cv2.imread(img_path)[:,:,::-1])
    plt.xticks([])

    plt.yticks([])
    plt.title('Query')
    plt.show()
    
def show_imgs(similar_list,titles=None):
    figure_size = 1 #* row number 
    length = len(similar_list)
    figure_size = figure_size*10 + length
    plt.figure(dpi = 300)

    for idx in range(length):
        # pos = str(figure_size*10 + idx +1)
        pos = figure_size*10 + idx +1
        plt.subplot(pos,title=str(idx + 1) if titles is None else titles[idx])
        
        plt.imshow(cv2.imread(similar_list[idx])[:,:,::-1])
        plt.xticks([])
        plt.yticks([])
    plt.show()



    
def show_imgs2(similar_list,titles=None):
    figure_size = 1 #* row number 
    length = len(similar_list)
    figure_size = figure_size*10 + length
    plt.figure(dpi = 300)

    for idx in range(length):
        # pos = str(figure_size*10 + idx +1)
        pos = figure_size*10 + idx +1
        plt.subplot(pos,title=str(idx + 1) if titles is None else titles[idx])
        
        plt.imshow(similar_list[idx][:,:,::-1])
        plt.xticks([])
        plt.yticks([])
    plt.show()







# Print iterations progress (thanks StackOverflow)
def printProgress(iteration, total, prefix='', suffix='', decimals=1, barLength=100):
    """
    Call in a loop to create terminal progress bar
    @params:
        iteration   - Required  : current iteration (Int)
        total       - Required  : total iterations (Int)
        prefix      - Optional  : prefix string (Str)
        suffix      - Optional  : suffix string (Str)
        decimals    - Optional  : positive number of decimals in percent complete (Int)
        barLength   - Optional  : character length of bar (Int)
    """
    formatStr       = "{0:." + str(decimals) + "f}"
    percents        = formatStr.format(100 * (iteration / float(total)))
    filledLength    = int(round(barLength * iteration / float(total)))
    bar             = '' * filledLength + '-' * (barLength - filledLength)
    sys.stdout.write('\r%s |%s| %s%s %s' % (prefix, bar, percents, '%', suffix)),
    if iteration == total:
        sys.stdout.write('\x1b[2K\r')
    sys.stdout.flush()


'''
description:  process by multple threshold
return {*}
'''
def process_mp(function,function_parameter_list,num_threads=64,\
                prefix='processing with multiple threads:',suffix = "done"):

    num_sample = len(function_parameter_list)
    with futures.ProcessPoolExecutor(max_workers=num_threads) as executor:
        
        fs = [executor.submit(function, parameters) for parameters in function_parameter_list]

        for i, f in enumerate(futures.as_completed(fs)):
            printProgress(i, num_sample, prefix=prefix, suffix=suffix, barLength=40)





'''
description: 
return {*}
'''
def process_mp_with_feedback(function,function_parameter_list,num_threads=64,\
                prefix='processing with multiple threads:',suffix = "done"):

    num_sample = len(function_parameter_list)
    retuen_val = []
    with futures.ProcessPoolExecutor(max_workers=num_threads) as executor:
        
        fs = [executor.submit(function, parameters) for parameters in function_parameter_list]

        for i, f in enumerate(futures.as_completed(fs)):
            printProgress(i, num_sample, prefix=prefix, suffix=suffix, barLength=40)
            retuen_val.append(f.result())
    return retuen_val

